home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Archive-tools
/
DandStoQIF2.sea
/
DandStoQIF2.c
next >
Wrap
C/C++ Source or Header
|
1994-01-21
|
12KB
|
596 lines
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/*
* Copyright 1993 by Scott Pendleton
* Copyright 1994 by David A. Willcox
* All rights reserved.
*
* This software is provide "as is." Use at your own risk.
*
* This software may be distributed free of charge, as long as this
* notice is included. No fee may be charged beyond connection
* charges for downloading from a bulletin board or on-line service,
* unless express permission is obtained from the authors.
*/
#define MAX_FILENAME 34
#define MAX_LINEWIDTH 512
#define MAXTRANS 20 /* max accts in a transaction */
#define MAXFIELD 11 /* max fields scanned from a line */
struct acttrans /* info about one acct in a transaction */
{
struct acctalias *ac_cat; /* alias of category */
char ac_dep[20]; /* amt deposited */
char ac_with[20]; /* amt withdrawn */
char ac_descr[60]; /* a description */
} acttrans[MAXTRANS], actbase;
struct acctalias
{
struct acctalias *aa_link; /* next alias */
char *aa_dnsname; /* name in input file */
char *aa_qifname; /* name in output file */
char *aa_type; /* type of account */
int aa_prio; /* "priority" of this acct */
} *Firstalias;
char transdate[10];
char cknumber[8];
char payToFrom[60];
char Cleared[5];
char *Fields[MAXFIELD+1]; /* fields scanned from line */
char linebuf[MAX_LINEWIDTH]; /* buffer for input line */
int smart_map = 1; /* 0=>print all, 1=>ignore dups, 2=>prt as comment */
struct acctalias *fundacct = 0;
char outfname[MAX_FILENAME];
FILE *outfptr;
int doflag = 0;
int postdummy = 0;
int duptrans = 0;
/* Prototypes */
void scantran(struct acttrans *ac);
void dumpit(int nt);
int isdate(char *str);
void clrtrans(struct acttrans *);
int readaliases(char *fname);
struct acctalias *mapalias (char *name);
struct acctalias *newalias(char *dnsname, char *qifname, char *type, char *prio);
int getline(FILE *fp);
char *savestr (char *);
struct acctalias *isnewacct(char *);
main()
{
FILE *infptr;
char infname[MAX_FILENAME], Htype[20];
char c;
int count,i;
int skipped;
struct acctalias *newfundacct;
smart_map = -1;
do
{
printf ("Try to suppress duplicate transactions? (y/n): ");
gets (infname);
switch (infname[0])
{
case 'y':
case 'Y':
smart_map = 1;
break;
case 'n':
case 'N':
smart_map = 0;
break;
case 'c':
case 'C':
smart_map = 2;
break;
}
} while (smart_map < 0);
if (smart_map > 0)
{
postdummy = -1;
do
{
printf ("Post dup transaction to @Dummy if cleared? (y/n): ");
gets (infname);
switch (infname[0])
{
case 'y':
case 'Y':
postdummy = 1;
break;
case 'n':
case 'N':
postdummy = 0;
break;
}
} while (postdummy < 0);
}
doflag = -1;
do
{
printf ("Include flags in description as <FLG>? (y/n): ");
gets (infname);
switch (infname[0])
{
case 'y':
case 'Y':
doflag = 1;
break;
case 'n':
case 'N':
doflag = 0;
break;
}
} while (doflag < 0);
do
{
printf ("Name of acct map file (or Return)? ");
gets (infname);
if (infname[0] == 0)
break;
} while (readaliases(infname) < 0);
for (;;)
{
i=0;
skipped = 0;
printf("File Name or Return? ");
gets(infname);
if (infname[0] == 0)
break;
infptr = fopen(infname,"r");
if (!infptr)
{
printf("\n\nError opening the file: %s\n",infname);
continue;
}
count = 0;
while (getline(infptr) >= 0)
{
if (isdate(Fields[0]))
{
dumpit(count);
count = 0;
i=i+1;
if ((i % 10) == 0)
printf("Number of Transactions Converted: %i\r",i);
strcpy(transdate,Fields[0]);
strcpy(cknumber, Fields[1]);
strcpy(payToFrom, Fields[2]);
strcpy(Cleared, Fields[6]);
scantran(&actbase);
}
else if ((newfundacct = isnewacct(Fields[0])) != 0)
{
/* this is start of new funding account */
dumpit(count); /* get rid of old stuff */
report (i, skipped);
skipped = 0;
if (outfptr)
{
fclose (outfptr);
outfptr = 0;
}
fundacct = newfundacct;
count = -1;
i = 0;
}
else
{
if (*Fields[0] != 0 /* header or trailer */
|| *Fields[3] == 0 /* no category */
|| count < 0) /* haven't found start of transaction, yet */
{
skipped++;
continue;
}
if (count <= MAXTRANS)
{
scantran(&acttrans[count]);
count= count + 1;
}
else
{
printf ("Too many transactions\n");
}
}
}
dumpit(count);
fclose(infptr);
if (outfptr)
{
fclose(outfptr);
outfptr = 0;
}
report (i, skipped);
skipped = 0;
printf ("\n");
}
printf ("All done. Please hit RETURN to exit\n\n");
fgets(linebuf,MAX_LINEWIDTH,infptr);
}
report (count, skipped)
{
char buf[2];
if (fundacct)
{
printf ("\n%d Transactions processed for acct %s(%s)\n",
count, fundacct->aa_dnsname, fundacct->aa_qifname);
#if 0
if (skipped > 0)
printf (" %d garbage lines skipped\n", skipped);
#endif
if (duptrans)
printf (" %d cleared dup transactions\n", duptrans);
printf ("Press RETURN to contine\n");
fgets (buf, sizeof buf, stdin);
}
duptrans = 0;
}
void
dumpit(nt)
int nt; /* number of transactions */
{
register struct acttrans *ap;
char *comment = "";
register int acprio;
int clrchar = 'X';
if (nt <= 0)
return;
if (smart_map)
{
int possdup;
possdup = 0;
acprio = actbase.ac_cat->aa_prio;
for (ap = &acttrans[nt-1]; ap >= acttrans; --ap)
{
if (ap->ac_cat->aa_prio < acprio)
continue;
if (ap->ac_cat->aa_prio == acprio)
{
int cmp;
cmp = strcmp (ap->ac_cat->aa_qifname,
actbase.ac_cat->aa_qifname);
if (cmp < 0)
continue;
if (cmp == 0)
{
possdup = 1;
continue;
}
}
comment = "@";
}
if (*comment != 0)
{
if (postdummy && Cleared[0] != 0)
{ /* turn this into posting to "@Dummy" */
nt = 1;
acttrans[0].ac_cat = mapalias("@Dummy");
strcpy(acttrans[0].ac_dep, actbase.ac_dep);
strcpy(acttrans[0].ac_with, actbase.ac_with);
strcpy(acttrans[0].ac_descr, "Reconciled Transfer");
comment = "";
}
else if (smart_map == 1)
return; /* Don't print at all */
}
else if (possdup)
{
printf ("Transaction ");
if (cknumber[0] != 0)
printf("number %s ", cknumber);
printf ("on date %s might be duplicated\n",
transdate);
}
}
if (outfptr == 0)
{
if (fundacct == 0)
{
printf ("ERROR: Transaction with no output file\n");
return;
}
strcpy(outfname,fundacct->aa_qifname);
strcat(outfname,".QIF");
outfptr = fopen (outfname, "w");
if (outfptr == 0)
{
printf ("Error opening output file %s\n\n", outfname);
return;
}
if (fundacct->aa_type == 0 || *fundacct->aa_type == 0)
fundacct->aa_type = "Bank";
printf ("\nOpening output file %s for acct %s type %s\n",
outfname, fundacct->aa_dnsname, fundacct->aa_type);
fprintf(outfptr,"!Type:%s\n",fundacct->aa_type);
}
fprintf(outfptr,"%sD%s\n", comment, transdate);
if (actbase.ac_dep[0] != 0)
fprintf(outfptr,"%sT%s\n",comment, actbase.ac_dep);
if (actbase.ac_with[0] != 0)
fprintf(outfptr,"%sT-%s\n",comment, actbase.ac_with);
if (Cleared[0] != 0)
fprintf(outfptr,"%sC%c\n", comment, clrchar);
if (cknumber[0] != 0)
fprintf(outfptr,"%sN%s\n",comment, cknumber);
fprintf(outfptr,"%sP%s\n",comment, payToFrom);
if (actbase.ac_descr[0] != 0)
fprintf(outfptr, "%sM%s\n", comment, actbase.ac_descr);
if (nt <= 1)
{
if (actbase.ac_descr[0] || acttrans[0].ac_descr[0])
{
if (actbase.ac_descr[0])
{
fprintf (outfptr, "%sM%s", comment, actbase.ac_descr);
if (acttrans[0].ac_descr[0])
fprintf (outfptr, "; %s\n", acttrans[0].ac_descr);
else
fprintf (outfptr, "\n");
}
else
fprintf (outfptr, "%sM%s\n", comment, acttrans[0].ac_descr);
}
fprintf (outfptr, "%sL%s\n",
comment, acttrans[0].ac_cat->aa_qifname);
}
else
{
if (actbase.ac_descr[0] != 0)
fprintf(outfptr, "%sM%s\n", comment, actbase.ac_descr);
for (ap = acttrans; ap < &acttrans[nt]; ++ap)
{
fprintf (outfptr, "%sS%s\n", comment,
ap->ac_cat->aa_qifname);
if (ap->ac_descr[0])
fprintf (outfptr, "%sE%s\n", comment, ap->ac_descr);
if (ap->ac_dep[0])
fprintf(outfptr, "%s$-%s\n",
comment, ap->ac_dep);
if (ap->ac_with[0])
fprintf(outfptr, "%s$%s\n",
comment, ap->ac_with);
}
}
fprintf(outfptr,"%s^\n", comment);
}
/* checks to see if str is a date. Really only checks to see if there are 2 '/' in the */
/* str. very crude! */
int
isdate(str)
register char *str;
{
int count;
count = 0;
while (*str)
{
if (*str == '/')
count++;
else if (!isdigit(*str))
return (0);
++str;
}
if (count != 2)
return(0);
return(1);
}
/*
* Clear out a transaction
*/
void
clrtrans(ac)
register struct acttrans *ac;
{
ac->ac_cat = 0;
ac->ac_dep[0] = 0;
ac->ac_with[0] = 0;
ac->ac_descr[0] = 0;
}
/*
* Scan info about a trans
*/
void
scantran(ac)
register struct acttrans *ac;
{
ac->ac_cat = mapalias (Fields[3]);
strcpy(ac->ac_dep, Fields[4]);
strcpy(ac->ac_with, Fields[5]);
strcpy(ac->ac_descr, Fields[10]);
if (doflag && Fields[7][0])
{
strcat (ac->ac_descr, "<");
strcat (ac->ac_descr, Fields[7]);
strcat (ac->ac_descr, ">");
}
}
/* return permanent copy of a string */
char *
savestr(char *str)
{
char *ret;
if (str == 0 || *str == 0)
return ("");
ret = malloc (strlen (str)+1);
strcpy (ret, str);
return (ret);
}
struct acctalias *
newalias (register char *dnsname, register char *qifname, char *type, char *priop)
{
register struct acctalias *ap;
ap = malloc (sizeof *ap);
ap->aa_link = Firstalias;
Firstalias = ap;
ap->aa_qifname = savestr(qifname);
ap->aa_dnsname = savestr(dnsname);
ap->aa_type = savestr(type);
if (priop && *priop != 0)
{
ap->aa_prio = atoi(priop);
if (ap->aa_prio < 0)
ap->aa_prio = 0;
}
else if (*qifname == '[')
ap->aa_prio = 1;
else
ap->aa_prio = 0;
#if 0
printf ("Create alias \"%s\" for \"%s\", prio %d\n",
ap->aa_qifname, ap->aa_dnsname, ap->aa_prio);
#endif
return (ap);
}
/*
* read in the alias file
*/
int
readaliases (char *fname)
{
FILE *afile;
char dnsname[60];
char qifname[32];
struct acctalias *ap;
afile = fopen (fname, "r");
if (afile == NULL)
return (-1);
while (getline (afile) >= 0)
{
if (*Fields[0] == 0 || *Fields[1] == 0)
continue; /* missing field, so skip */
newalias (Fields[0], Fields[1], Fields[3], Fields[2]);
}
fclose (afile);
return (0);
}
/*
* If input name is found in alias list, replace with its alias
*/
struct acctalias *
mapalias (iname)
register char *iname;
{
register struct acctalias *ap;
for (ap = Firstalias; ap != 0; ap = ap->aa_link)
{
if (ap->aa_dnsname[0] == iname[0]
&& ap->aa_dnsname[1] == iname[1]
&& strcmp (ap->aa_dnsname, iname) == 0)
{ /* found a match */
return (ap);
}
}
ap = newalias (iname, iname, 0, 0);
return (ap);
}
/*
* Read an input line and parse it into fields
* Return number of fields scanned, or -1 for EOF
*/
int
getline(FILE *fp)
{
register char **tp; /* pointer to current field */
register char *lp; /* latest char in buffer */
if (fgets(linebuf, sizeof linebuf, fp) == NULL)
return (-1);
for (tp=Fields, lp=linebuf; tp < &Fields[MAXFIELD]; )
{ /* split line into tab-separated fields */
*tp++ = lp; /* record start of field */
while (*lp && *lp != '\t' && *lp != '\n')
++lp; /* find end of field */
if (*lp == 0)
break;
*lp++ = 0; /* null-terminate field */
}
while (tp < &Fields[MAXFIELD])
{
*tp++ = "";
}
#if 0
printf ("getline returns %d: ", tp-Fields);
{
int i;
for (i = 0; i < MAXFIELD; ++i)
printf (" \"%s\"", Fields[i]);
printf ("\n");
}
#endif
return (tp-Fields);
}
/*
* Check for "Funding account: " line that designates a new funding account
*/
char tag[] = "Funding account: ";
struct acctalias *
isnewacct (char *line)
{
register char *pl, *pt;
register struct acctalias *ap;
for (pl = line, pt = tag; *pt; ++pl, ++pt)
{
if (*pl != *pt)
return (0);
}
/* The initial tag is correct. Look up the funding account */
return (mapalias (pl));
}